<?php

use \Firebase\JWT\JWT;

use think\facade\Db;
use OSS\OssClient;
use OSS\Core\OssException;

// token加解密Key
define("token_key", "qwegfeh48tu1@285478");

function notice($msg = "请求成功", $code = 200)
{
    $datas = [
        "code" => $code,
        "msg" => $msg
    ];

    return json($datas);
}

// 数据请求成功统一返回
function success($data = array(), $msg = "请求成功", $code = 200)
{

    $datas = [
        "code" => $code,
        "msg" => $msg,
        "result" => $data,
    ];

    return json($datas, $code);
}

// 数据请求失败统一返回
function error($msg = "数据请求失败", $code = 400)
{

    $datas = [
        "code" => $code,
        "msg" => $msg,
    ];

    return json($datas);
}

//验证token并获取用户信息
function checkToken($token)
{
    $key = constant("token_key");
    $status = array("code" => 420);

    $tks = explode('.', $token);

    if (empty($token)) {
        abort(410, 'token为空');
    }

    if (count($tks) != 3) {
        abort(420, 'token格式错误');
    }

    try {
        JWT::$leeway = 60; //当前时间减去60，把时间留点余地
        $decoded = JWT::decode($token, $key, array('HS256')); //HS256方式，这里要和签发的时候对应
        $arr = (array)$decoded;
        $res['code'] = 200;
        $res['result'] = $arr['data'];
        return $res;
    } catch (\Firebase\JWT\SignatureInvalidException $e) {
        //签名不正确
        $status['msg'] = "token签名不正确";
        return $status;
    } catch (\Firebase\JWT\BeforeValidException $e) {
        // 签名在某个时间点之后才能用
        $status['msg'] = "token已失效";
        return $status;
    } catch (\Firebase\JWT\ExpiredException $e) {
        // token过期
        $status['msg'] = "token已失效";
        return $status;
    } catch (Exception $e) {
        //其他错误
        $status['msg'] = $e->getMessage();
        return $status;
    }
}

function httpRequest($url, $data = null, $method = 'GET', $headers = array(), $https = true)
{
    // 创建一个新cURL资源
    $ch = curl_init();
    // 设置URL和相应的选项

    curl_setopt($ch, CURLOPT_URL, $url);
    //要访问的网站 //启用时会将头文件的信息作为数据流输出。
    curl_setopt($ch, CURLOPT_HEADER, false);
    //将curl_exec()获取的信息以字符串返回，而不是直接输出。
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    if ($https) {

        //FALSE 禁止 cURL 验证对等证书（peer's certificate）。
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        //验证主机 }
        if ($method == 'POST') {
            curl_setopt($ch, CURLOPT_POST, true);

            //发送 POST 请求  //全部数据使用HTTP协议中的 "POST" 操作来发送。
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        }
        // 抓取URL并把它传递给浏览器
        $content = curl_exec($ch);
        //关闭cURL资源，并且释放系统资源
        curl_close($ch);

        return json_decode($content, true);

    }
}

//阿里云Oss上传配置
function alYunOSS($filePath, $Extension)
{

    $alYunOSS = Db::name("system")->where("config", "uploadType")->value("extend");
    $alYunOSS = json_decode($alYunOSS, true);

    $accessKeyId = $alYunOSS["accessKeyId"];
    $accessKeySecret = $alYunOSS["accessKeySecret"];
    $endpoint = $alYunOSS["endpoint"];
    $bucket = $alYunOSS["OssName"];    // 存储空间名称
    $object = date("Ymd") . time() . rand(10000, 99999) . "." . $Extension;    // 文件名称

    try {
        $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, true);

        $rel = $ossClient->uploadFile($bucket, $object, $filePath);
        return ["code" => 1, "url" => $rel["info"]["url"]];
    } catch (OssException $e) {
        return ["code" => 0, "msg" => $e->getMessage()];
    }
}

/**
 * 解析sql语句
 * @param string $content sql内容
 * @param int $limit 如果为1，则只返回一条sql语句，默认返回所有
 * @param array $prefix 替换表前缀
 * @return array|string 除去注释之后的sql语句数组或一条语句
 */
function parse_sql($sql = '', $limit = 0, $prefix = [])
{
    // 被替换的前缀
    $from = '';
    // 要替换的前缀
    $to = '';

    // 替换表前缀
    if (!empty($prefix)) {
        $to = current($prefix);
        $from = current(array_flip($prefix));
    }

    if ($sql != '') {
        // 纯sql内容
        $pure_sql = [];

        // 多行注释标记
        $comment = false;

        // 按行分割，兼容多个平台
        $sql = str_replace(["\r\n", "\r"], "\n", $sql);
        $sql = explode("\n", trim($sql));

        // 循环处理每一行
        foreach ($sql as $key => $line) {
            // 跳过空行
            if ($line == '') {
                continue;
            }

            // 跳过以#或者--开头的单行注释
            if (preg_match("/^(#|--)/", $line)) {
                continue;
            }

            // 跳过以/**/包裹起来的单行注释
            if (preg_match("/^\/\*(.*?)\*\//", $line)) {
                continue;
            }

            // 多行注释开始
            if (substr($line, 0, 2) == '/*') {
                $comment = true;
                continue;
            }

            // 多行注释结束
            if (substr($line, -2) == '*/') {
                $comment = false;
                continue;
            }

            // 多行注释没有结束，继续跳过
            if ($comment) {
                continue;
            }

            // 替换表前缀
            if ($from != '') {
                $line = str_replace('`' . $from, '`' . $to, $line);
            }
            if ($line == 'BEGIN;' || $line == 'COMMIT;') {
                continue;
            }
            // sql语句
            array_push($pure_sql, $line);
        }

        // 只返回一条语句
        if ($limit == 1) {
            return implode([],$pure_sql);
        }

        // 以数组形式返回sql语句
        $pure_sql = implode("\n",$pure_sql);
        $pure_sql = explode(";\n", $pure_sql);
        return $pure_sql;
    } else {
        return $limit == 1 ? '' : [];
    }
}

/**
 * @description: 获取一个日期范围内的日期
 * @param {interval:日期范围,type：取值类型，-：获取之前日期；+：获取之后的日期}
 * @return:
 */
function getDateInterval(int $interval, string $type): array
{
    $dateArr = [];
    for ($i = $interval - 1; $i >= 0; $i--) {
        array_push($dateArr, date('Y-m-d', strtotime("{$type}{$i} day")));
    }
    if ($type == '+') $dateArr = array_reverse($dateArr);
    return $dateArr;
}


/**重组树形结构数据
* @arr: 组数
 * @id:父级id
 * @level:树形层级
*/

function makeTree($arr,$level = 0,$id = 0)
{
    $list =array();
    foreach ($arr as $k=>$v){
        if ($v['pid'] == $id){
            $v['level']=$level;
            $v['children'] = makeTree($arr,$level+1,$v['id']);
            $list[] = $v;
        }
    }
    return $list;
}
